import React, { useState, useEffect, useRef, useCallback, useMemo } from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import { novelsApi } from '../services/api';
import { contentManager, splitContentIntoChunks, detectEncoding, formatChapterContent } from '../services/contentSplitter';
import { novelOperations, chapterOperations, progressOperations } from '../db/operations';
import db from '../db/database';
import { FiChevronLeft, FiSettings, FiSun, FiMoon, FiAlignCenter, FiBookOpen, FiWifi, FiWifiOff, FiDownload, FiCheck, FiX, FiChevronRight, FiMenu, FiBook, FiZap, FiArrowLeft, FiList, FiMinus, FiPlus } from 'react-icons/fi';

// 将防抖函数移到组件外部
const debounce = (fn, delay) => {
  let timer = null;
  return (...args) => {
    if (timer) clearTimeout(timer);
    timer = setTimeout(() => fn(...args), delay);
  };
};

// 创建虚拟滚动组件
const VirtualizedParagraphs = React.memo(({ paragraphs, fontSize, lineHeight, fontFamily }) => {
  const containerRef = useRef(null);
  const [visibleRange, setVisibleRange] = useState({ start: 0, end: 50 });
  const [containerHeight, setContainerHeight] = useState(0);
  
  // 安全DOM操作工具
  const safeDOM = {
    getAttribute: (element, attribute) => {
      if (!element) return null;
      try {
        return element.getAttribute(attribute);
      } catch (e) {
        return null;
      }
    },
    
    setAttribute: (element, attribute, value) => {
      if (!element) return;
      try {
        if (element && typeof element.setAttribute === 'function') {
          element.setAttribute(attribute, value);
        }
      } catch (e) {
        console.warn(`setAttribute 错误:`, e);
      }
    },
    
    addEventListener: (element, event, handler) => {
      if (!element) return;
      try {
        element.addEventListener(event, handler);
      } catch (e) {
        console.warn(`addEventListener 错误:`, e);
      }
    },
    
    removeEventListener: (element, event, handler) => {
      if (!element) return;
      try {
        element.removeEventListener(event, handler);
      } catch (e) {
        console.warn(`removeEventListener 错误:`, e);
      }
    },
    
    contains: (parent, child) => {
      if (!parent || !child) return false;
      try {
        return parent.contains(child);
      } catch (e) {
        return false;
      }
    }
  };
  
  // 估算单行高度
  const lineHeightPx = useMemo(() => {
    return Math.ceil(fontSize * lineHeight);
  }, [fontSize, lineHeight]);
  
  // 估算段落高度
  const estimateParagraphHeight = useCallback((paragraph) => {
    // 简单估算：每70个字符一行，根据段落长度计算行数
    const charsPerLine = Math.floor(70 * (18 / fontSize)); // 随字体大小调整
    const lines = Math.ceil(paragraph.length / charsPerLine) || 1;
    return lines * lineHeightPx + 16; // 16px是段落下边距
  }, [fontSize, lineHeightPx]);
  
  // 计算每个段落的高度和位置
  const paragraphMetrics = useMemo(() => {
    let totalHeight = 0;
    const metrics = paragraphs.map((paragraph) => {
      const height = estimateParagraphHeight(paragraph);
      const position = totalHeight;
      totalHeight += height;
      return { height, position };
    });
    return { metrics, totalHeight };
  }, [paragraphs, estimateParagraphHeight]);
  
  // 处理滚动事件，更新可见范围
  const handleScroll = useCallback(() => {
    const container = containerRef.current;
    if (!container) return;
    
    const { scrollTop, clientHeight } = container;
    const buffer = clientHeight; // 上下各缓冲一屏
    
    let startIndex = 0;
    let endIndex = paragraphs.length - 1;
    
    // 找到开始索引
    for (let i = 0; i < paragraphMetrics.metrics.length; i++) {
      const metric = paragraphMetrics.metrics[i];
      if (metric.position + metric.height >= scrollTop - buffer) {
        startIndex = i;
        break;
      }
    }
    
    // 找到结束索引
    for (let i = startIndex; i < paragraphMetrics.metrics.length; i++) {
      const metric = paragraphMetrics.metrics[i];
      if (metric.position >= scrollTop + clientHeight + buffer) {
        endIndex = i - 1;
        break;
      }
    }
    
    setVisibleRange({ start: startIndex, end: endIndex });
  }, [paragraphs, paragraphMetrics]);
  
  // 监听容器大小变化
  useEffect(() => {
    const container = containerRef.current;
    if (!container) return;
    
    const resizeObserver = new ResizeObserver((entries) => {
      for (const entry of entries) {
        if (entry.target === container) {
          setContainerHeight(entry.contentRect.height);
        }
      }
    });
    
    try {
      resizeObserver.observe(container);
    } catch (e) {
      console.warn('ResizeObserver错误:', e);
    }
    
    return () => {
      try {
        resizeObserver.disconnect();
      } catch (e) {
        console.warn('ResizeObserver断开错误:', e);
      }
    };
  }, []);
  
  // 监听滚动事件
  useEffect(() => {
    const container = containerRef.current;
    if (!container) return;
    
    // 使用RAF确保DOM已更新
    let rafId;
    let isComponentMounted = true;  // 添加组件挂载标志
    
    const handleScrollSafely = () => {
      rafId = requestAnimationFrame(() => {
        if (!isComponentMounted) return;  // 检查组件是否仍然挂载
        
        const currentContainer = containerRef.current;
        if (currentContainer && safeDOM.contains(document.body, currentContainer)) {
          handleScroll();
        }
      });
    };
    
    safeDOM.addEventListener(container, 'scroll', handleScrollSafely);
    handleScrollSafely(); // 初始化可见范围
    
    return () => {
      isComponentMounted = false;  // 标记组件已卸载
      cancelAnimationFrame(rafId);
      
      // 安全地移除事件监听
      if (container) {
        safeDOM.removeEventListener(container, 'scroll', handleScrollSafely);
      }
    };
  }, [handleScroll, safeDOM]);
  
  // 渲染可见段落 - 将useMemo移到条件判断之前
  const visibleParagraphs = useMemo(() => {
    return paragraphs.slice(visibleRange.start, visibleRange.end + 1).map((paragraph, localIndex) => {
      const globalIndex = visibleRange.start + localIndex;
      return (
        <p 
          key={globalIndex} 
          className="mb-4"
          data-index={globalIndex}
        >
          {paragraph}
        </p>
      );
    });
  }, [paragraphs, visibleRange]);
  
  // 计算内容总高度，为了正确的滚动条
  const contentHeight = paragraphMetrics.totalHeight;
  
  // 计算内容的上下填充物高度，保持滚动位置正确
  const topPadding = visibleRange.start > 0 ? paragraphMetrics.metrics[visibleRange.start].position : 0;
  const bottomPadding = contentHeight - (
    visibleRange.end < paragraphMetrics.metrics.length - 1 
      ? paragraphMetrics.metrics[visibleRange.end].position + paragraphMetrics.metrics[visibleRange.end].height
      : contentHeight
  );
  
  // 使用简单渲染的段落
  const simpleParagraphs = useMemo(() => {
    return paragraphs.map((paragraph, index) => (
      <p key={index} className="mb-4" data-index={index}>
        {paragraph}
      </p>
    ));
  }, [paragraphs]);
  
  // 根据内容长度选择渲染方式
  if (paragraphs.length < 50) {
    return (
      <div ref={containerRef} className="h-full overflow-auto">
        <div>
          {simpleParagraphs}
        </div>
      </div>
    );
  }
  
  return (
    <div 
      ref={containerRef} 
      className="h-full relative overflow-auto"
    >
      <div style={{ height: contentHeight }}>
        <div style={{ paddingTop: topPadding, paddingBottom: bottomPadding }}>
          {visibleParagraphs}
        </div>
      </div>
    </div>
  );
});

// 简单通知组件
const SimpleNotification = ({ message, type = 'info', onClose }) => {
  const bgColor = type === 'error' ? 'bg-red-500' : type === 'warning' ? 'bg-yellow-500' : 'bg-blue-500';
  
  return (
    <div className={`fixed bottom-4 right-4 ${bgColor} text-white px-4 py-2 rounded shadow-lg z-50 flex items-center`}>
      <span>{message}</span>
      <button 
        className="ml-2 text-white hover:text-gray-200" 
        onClick={onClose}
      >
        <FiX />
      </button>
    </div>
  );
};

// 增加分批处理章节数据的函数
const processChunkedData = (data, chunkSize, processChunk, onComplete) => {
  let index = 0;
  
  const processNextChunk = () => {
    const start = index;
    const end = Math.min(index + chunkSize, data.length);
    
    if (start < data.length) {
      const chunk = data.slice(start, end);
      processChunk(chunk, start);
      
      index = end;
      setTimeout(processNextChunk, 0); // 使用setTimeout允许UI更新
    } else {
      if (onComplete) onComplete();
    }
  };
  
  processNextChunk();
};

// 创建单独的虚拟列表组件，不再作为回调函数
const ChapterVirtualList = React.memo(({ chapters, onSelect, currentChapterId, theme }) => {
  const listRef = useRef(null);
  const [visibleRange, setVisibleRange] = useState({ start: 0, end: 50 });
  const itemHeight = 36; // 每个章节项的高度，单位像素
  
  // 自定义防抖函数（在组件内部使用，避免使用hook）
  const debounce = (fn, delay) => {
    let timer = null;
    return (...args) => {
      if (timer) clearTimeout(timer);
      timer = setTimeout(() => fn(...args), delay);
    };
  };
  
  useEffect(() => {
    // 寻找当前章节的索引并滚动到该位置
    if (currentChapterId && chapters.length > 0 && listRef.current) {
      const index = chapters.findIndex(ch => ch.id === currentChapterId);
      if (index !== -1) {
        // 设置可见范围以包含当前章节
        const start = Math.max(0, index - 20);
        const end = Math.min(chapters.length, start + 50);
        setVisibleRange({ start, end });
        
        // 滚动到当前章节
        setTimeout(() => {
          if (listRef.current) {
            listRef.current.scrollTop = start * itemHeight;
          }
        }, 100);
      }
    }
  }, [currentChapterId, chapters, itemHeight]);
  
  // 使用组件内的防抖函数处理滚动事件
  const handleScroll = useMemo(() => {
    return debounce((e) => {
      if (!listRef.current) return;
      
      const scrollTop = e.target.scrollTop;
      const clientHeight = e.target.clientHeight;
      
      // 计算可见范围
      const start = Math.floor(scrollTop / itemHeight);
      const visibleItems = Math.ceil(clientHeight / itemHeight);
      const end = Math.min(chapters.length, start + visibleItems + 10); // 额外缓冲10项
      
      setVisibleRange({ start: Math.max(0, start - 5), end });
    }, 50);
  }, [chapters.length, itemHeight]);
  
  // 总高度
  const totalHeight = chapters.length * itemHeight;
  // 可见章节
  const visibleChapters = chapters.slice(visibleRange.start, visibleRange.end);
  // 顶部空白高度
  const topPadding = visibleRange.start * itemHeight;
  
  return (
    <div 
      ref={listRef}
      className="overflow-y-auto flex-1 h-full" 
      onScroll={handleScroll}
      style={{ position: 'relative' }}
    >
      <div style={{ height: `${totalHeight}px`, position: 'relative' }}>
        <div style={{ position: 'absolute', top: `${topPadding}px`, width: '100%' }}>
          {visibleChapters.map((chapter) => (
            <div 
              key={chapter.id}
              className={`p-2 ${theme.buttonHover} cursor-pointer flex items-center justify-between 
                ${currentChapterId === chapter.id ? 'bg-blue-100 dark:bg-blue-900' : ''} 
                border-b border-gray-100 dark:border-gray-800`}
              onClick={() => onSelect(chapter)}
              style={{ height: `${itemHeight}px` }}
            >
              <div className="flex-1 truncate">
                {chapter.title}
              </div>
              {/* 当前阅读的章节显示标记 */}
              {currentChapterId === chapter.id && (
                <div className="w-2 h-2 rounded-full bg-blue-500 ml-2"></div>
              )}
            </div>
          ))}
        </div>
      </div>
    </div>
  );
});

function Reader() {
  const { id } = useParams();
  const navigate = useNavigate();
  const contentRef = useRef(null);
  
  // 请求控制相关的引用
  const isLoadingRef = useRef(false);
  const fetchControllerRef = useRef(null);
  
  const [novel, setNovel] = useState(null);
  const [content, setContent] = useState('');
  const [chapters, setChapters] = useState([]);
  const [currentChapter, setCurrentChapter] = useState(null);
  const [loading, setLoading] = useState(true);
  const [loadingText, setLoadingText] = useState('加载中...');
  const [error, setError] = useState(null);
  const [chapterContent, setChapterContent] = useState('');
  const [paragraphs, setParagraphs] = useState([]);
  const [readingPosition, setReadingPosition] = useState(0);
  
  // 阅读记录状态
  const [lastReadTime, setLastReadTime] = useState(null);
  const [readingProgress, setReadingProgress] = useState(0);
  const [showContinueReading, setShowContinueReading] = useState(false);
  
  // 缓存状态
  const [isCaching, setIsCaching] = useState(false);
  const [isCached, setIsCached] = useState(false);
  const [cacheProgress, setCacheProgress] = useState(0);
  
  // 阅读设置状态
  const [showSettings, setShowSettings] = useState(false);
  const [settings, setSettings] = useState({
    fontSize: 18,
    lineHeight: 1.8,
    theme: 'light', // light, dark, sepia
    fontFamily: 'default',
    encoding: 'auto', // 新增编码设置，默认为自动检测
    maxChapterChars: 10000, // 新增章节最大长度设置，默认为10000
  });
  
  // 侧边栏状态
  const [showSidebar, setShowSidebar] = useState(false);
  
  // 章节列表分页状态
  const [visibleChaptersStart, setVisibleChaptersStart] = useState(0);
  const [visibleChaptersCount, setVisibleChaptersCount] = useState(100); // 初始只显示100章
  
  // 网络状态
  const [isOffline, setIsOffline] = useState(!navigator.onLine);
  const [showOfflineNotice, setShowOfflineNotice] = useState(false);
  const [permanentOfflineMode, setPermanentOfflineMode] = useState(localStorage.getItem('offlineMode') === 'true');
  
  // 诊断状态 - 防止重复和循环诊断
  const [hasRunDiagnosis, setHasRunDiagnosis] = useState(false);
  const [hasTriedDirectLoad, setHasTriedDirectLoad] = useState(false);
  const [hasCorrectedCache, setHasCorrectedCache] = useState(false);
  const [correctedIds] = useState(new Set()); // 用于记录已修复过的ID，防止重复修复
  
  // 通知状态
  const [notification, setNotification] = useState(null);
  
  // 显示通知的函数
  const showNotification = (message, type = 'info', duration = 3000) => {
    setNotification({ message, type });
    
    if (duration > 0) {
      setTimeout(() => {
        setNotification(null);
      }, duration);
    }
  };
  
  // 关闭通知
  const closeNotification = () => {
    setNotification(null);
  };
  
  // 添加保存阅读位置函数 - 提前定义，解决在使用前未初始化的问题
  const saveReadingPosition = useCallback(() => {
    if (!contentRef.current || !currentChapter || !id || chapters.length === 0) return;
    
    const position = contentRef.current.scrollTop;
    
    // 计算阅读总进度
    const chapterIndex = chapters.findIndex(ch => ch.id === currentChapter.id);
    const totalProgress = ((chapterIndex / chapters.length) * 100);
    const formattedProgress = totalProgress.toFixed(1);
    
    // 保存阅读进度
    progressOperations.saveProgress(
      id, 
      currentChapter.id, 
      position, 
      Date.now(),
      formattedProgress
    );
    
    // 更新状态
    setReadingProgress(parseFloat(formattedProgress));
    
    console.log(`已保存阅读位置: 章节=${currentChapter.title}, 位置=${position}, 进度=${formattedProgress}%`);
  }, [contentRef, currentChapter, id, chapters]);
  
  // 直接从数据库获取小说内容 - 用于离线模式的紧急情况
  const getNovelContentDirectly = useCallback(async (novelId) => {
    console.log(`尝试直接从数据库获取小说ID=${novelId}的内容...`);
    try {
      const numericId = parseInt(novelId, 10);
      
      // 直接从fullContents表获取
      const fullContents = await db.fullContents
        .filter(item => item.novelId == numericId)
        .toArray();
      
      console.log(`直接查询结果: 找到 ${fullContents.length} 条fullContents记录`);
      
      if (fullContents && fullContents.length > 0) {
        const fullContent = fullContents[0];
        
        if (fullContent && fullContent.data && typeof fullContent.data === 'string' && fullContent.data.length > 0) {
          console.log(`成功获取到小说内容，长度: ${fullContent.data.length}`);
          return fullContent.data;
        } else {
          console.error(`获取到的内容无效: ${fullContent ? '记录存在' : '记录不存在'}`);
          if (fullContent) {
            console.error(`内容类型: ${typeof fullContent.data}, 长度: ${fullContent.data ? fullContent.data.length : 0}`);
          }
          return null;
        }
      } else {
        console.error(`未找到小说 ${novelId} 的缓存内容记录`);
        return null;
      }
    } catch (err) {
      console.error(`直接获取小说内容失败:`, err);
      return null;
    }
  }, []);
  
  // 返回书架函数 - 移到这里以确保saveReadingPosition已定义
  const returnToBookshelf = useCallback(() => {
    // 保存当前阅读进度
    saveReadingPosition();
    
    // 导航回书架，添加状态标记表明是从阅读器返回
    // 添加额外标志，确保不会在返回后触发API加载
    navigate('/', { 
      state: { 
        fromReader: true,
        timestamp: Date.now() // 添加时间戳确保状态是新的
      } 
    });
  }, [navigate, saveReadingPosition]);
  
  // 切换永久离线模式 - 移到这里以确保saveReadingPosition已定义
  const toggleOfflineMode = () => {
    const newMode = !permanentOfflineMode;
    
    // 如果是切换到离线模式，询问是否切换到本地书架
    if (newMode && !permanentOfflineMode) {
      if (window.confirm('是否切换到本地书架模式？\n\n在本地书架模式下，您只能访问已缓存的小说。')) {
        // 保存当前阅读进度
        saveReadingPosition();
        
        // 导航回书架，添加状态标记表明是从阅读器返回，需要切换到离线模式
        navigate('/', { 
          state: { 
            fromReader: true,
            timestamp: Date.now(),
            switchToOfflineMode: true 
          } 
        });
        return; // 不继续执行后续代码
      }
    }
    
    // 正常切换离线模式
    setPermanentOfflineMode(newMode);
    localStorage.setItem('offlineMode', newMode);
    
    // 如果切换为在线模式，需要检查实际网络状态
    if (!newMode) {
      setIsOffline(!navigator.onLine);
    } else {
      // 强制为离线模式
      setIsOffline(true);
    }
  };
  
  // 监听网络状态变化，并提供离线提醒
  useEffect(() => {
    // 网络变化处理函数
    const handleOnline = () => {
      if (!permanentOfflineMode) {
        setIsOffline(false);
        setShowOfflineNotice(false);
        console.log('网络已连接，切换到在线模式');
      } else {
        console.log('网络已连接，但保持永久离线模式');
      }
    };
    
    const handleOffline = () => {
      setIsOffline(true);
      console.log('检测到网络断开，切换到离线模式');
      console.log('离线模式下将尝试从IndexedDB缓存加载数据');
      
      if (!permanentOfflineMode) {
        setShowOfflineNotice(true);
        
        // 弹出提示询问是否切换到本地书架
        if (window.confirm('检测到网络已断开，是否切换到本地书架模式？\n\n在本地书架模式下，您只能访问已缓存的小说。')) {
          // 保存当前阅读进度
          saveReadingPosition();
          
          // 导航回书架，添加状态标记表明是从阅读器返回，需要切换到离线模式
          navigate('/', { 
            state: { 
              fromReader: true,
              timestamp: Date.now(),
              switchToOfflineMode: true 
            } 
          });
        } else {
          // 5秒后自动隐藏提示
          setTimeout(() => {
            setShowOfflineNotice(false);
          }, 5000);
        }
      }
    };
    
    // 添加网络状态监听
    window.addEventListener('online', handleOnline);
    window.addEventListener('offline', handleOffline);
    
    // 卸载时移除监听
    return () => {
      window.removeEventListener('online', handleOnline);
      window.removeEventListener('offline', handleOffline);
    };
  }, [permanentOfflineMode, navigate, saveReadingPosition]);
  
  // 诊断小说存储状态
  async function diagnoseNovelStorage(novelId) {
    console.log(`开始诊断小说 ${novelId} 存储状态...`);
    
    // 如果已经修复过这个ID，直接从本地缓存获取结果
    if (correctedIds.has(parseInt(novelId, 10))) {
      console.log(`小说 ${novelId} 已经过验证修复，跳过重复诊断`);
      return { 
        novelInfo: undefined,
        hasCacheFlag: false, 
        hasFullContent: false,
        fullContentLength: 0,
        isContentValid: false,
        wasFixed: true // 标记为已修复
      };
    }
    
    try {
      let novelInfo = null;
      
      // 优先直接从数据库获取
      try {
        const numericId = parseInt(novelId, 10);
        const directNovel = await db.novels.get(numericId);
        if (directNovel) {
          console.log(`直接从数据库获取到小说信息:`, directNovel);
          novelInfo = directNovel;
        }
      } catch (directErr) {
        console.error(`直接获取小说 ${novelId} 信息失败:`, directErr);
      }
      
      // 如果直接获取失败，再尝试通过novelOperations获取
      if (!novelInfo) {
        try {
          novelInfo = await novelOperations.getNovel(novelId);
        } catch (opErr) {
          console.error(`通过novelOperations获取小说 ${novelId} 信息失败:`, opErr);
        }
      }
      
      // 如果找不到小说信息，先尝试从数据库获取所有小说列表作为参考
      if (!novelInfo) {
        console.log(`未能获取到ID=${novelId}的小说信息，检查数据库中的小说列表...`);
        try {
          const allNovels = await db.novels.toArray();
          if (allNovels.length > 0) {
            console.log('数据库中有 ' + allNovels.length + ' 本小说:', 
              allNovels.map(n => `ID:${n.id}, 名称:${n.name}`)
            );
            // 尝试通过ID查找匹配的小说
            const matchingNovel = allNovels.find(n => n.id === parseInt(novelId, 10));
            if (matchingNovel) {
              console.log(`在数据库列表中找到匹配的小说:`, matchingNovel);
              novelInfo = matchingNovel;
            }
          } else {
            console.log('数据库中没有小说记录');
          }
        } catch (e) {
          console.error('获取数据库小说列表失败:', e);
        }
      }
      
      let hasCacheFlag = false;
      let hasFullContent = false;
      let fullContentLength = 0;
      let isContentValid = false;
      
      if (novelInfo) {
        // 检查缓存标志
        hasCacheFlag = novelInfo.cached === true;
        
        // 检查fullContents表
        console.log(`检查fullContents表，查询ID=${novelId}...`);
        try {
          const numericId = parseInt(novelId, 10);
          const fullContents = await db.fullContents
            .filter(item => item.novelId == numericId)
            .toArray();
            
          console.log(`查询结果: 找到 ${fullContents.length} 条记录`);
          
          if (fullContents && fullContents.length > 0) {
            const fullContent = fullContents[0];
            hasFullContent = true;
            fullContentLength = fullContent.data ? fullContent.data.length : 0;
            isContentValid = Boolean(fullContent.data && typeof fullContent.data === 'string' && fullContent.data.length > 0);
            
            console.log(`找到完整内容，长度: ${fullContentLength}，有效性: ${isContentValid}`);
            if (isContentValid) {
              console.log(`内容样本: "${fullContent.data.substring(0, 100)}..."`);
            }
          }
        } catch (err) {
          console.error('检查缓存内容失败:', err);
        }
        
        // 如果标记与实际情况不符，主动修复（仅修复一次）
        if (hasCacheFlag !== isContentValid && !correctedIds.has(parseInt(novelId, 10))) {
          try {
            // 更新数据库中的标记
            await db.novels.update(parseInt(novelId, 10), { cached: isContentValid });
            console.log(`已修复小说 ${novelId} 的缓存标记: ${isContentValid}`);
            // 记录已修复的ID
            correctedIds.add(parseInt(novelId, 10));
          } catch (fixErr) {
            console.error(`修复缓存标记失败:`, fixErr);
          }
        }
      }
      
      const result = { 
        novelInfo, 
        hasCacheFlag, 
        hasFullContent, 
        fullContentLength, 
        isContentValid 
      };
      
      console.log(`小说 ${novelId} 缓存诊断完成: `, result);
      
      return result;
    } catch (err) {
      console.error(`诊断小说 ${novelId} 存储状态失败:`, err);
      return { 
        error: err.message,
        novelInfo: null,
        hasCacheFlag: false,
        hasFullContent: false,
        fullContentLength: 0,
        isContentValid: false
      };
    }
  }
  
  // 手动缓存小说
  const handleCacheNovel = async () => {
    if (isCaching || isCached || !novel) return;
    
    try {
      setIsCaching(true);
      setCacheProgress(0);
      
      // 从服务器获取全部内容
      const novelData = await novelsApi.getNovel(id);
      if (!novelData) {
        throw new Error('获取小说信息失败');
      }
      
      // 初始化缓存进度
      const totalChunks = novelData.chunks || 1;
      let allContent = '';
      
      // 分片下载
      for (let i = 0; i < totalChunks; i++) {
        const progress = Math.round(((i + 1) / totalChunks) * 100);
        setCacheProgress(progress);
        
        // 传递编码设置
        const options = settings.encoding !== 'auto' ? { encoding: settings.encoding } : {};
        const chunk = await novelsApi.getNovelChunk(id, i, null, options);
        
        if (chunk && chunk.data) {
          allContent += chunk.data;
        }
      }
      
      // 缓存到本地
      await novelOperations.cacheNovel(novelData, allContent);
      
      // 更新状态
      setIsCached(true);
      
      // 显示成功提示
      showNotification(`小说《${novel.name}》已成功缓存，现在可以离线阅读`, 'info');
    } catch (err) {
      console.error('缓存小说失败:', err);
      showNotification(`缓存失败: ${err.message || '未知错误'}`, 'error');
    } finally {
      setIsCaching(false);
      setCacheProgress(0);
    }
  };
  
  // 添加IndexedDB诊断函数
  const diagnoseIndexedDB = useCallback(async () => {
    // 防止重复诊断
    if (hasRunDiagnosis) return false;
    
    console.log('开始诊断IndexedDB状态...');
    setHasRunDiagnosis(true);
    
    try {
      // 检查IndexedDB连接
      console.log('检查IndexedDB连接...');
      const isDbOpen = db.isOpen();
      console.log(`数据库连接状态: ${isDbOpen ? '已打开' : '未打开'}`);
      
      // 如果数据库未打开，尝试打开
      if (!isDbOpen) {
        console.log('尝试打开数据库连接...');
        try {
          await db.open();
          console.log('数据库连接已成功打开');
        } catch (openErr) {
          console.error('打开数据库连接失败:', openErr);
        }
      }
      
      // 检查表信息
      console.log('获取数据库表信息...');
      const tables = ['novels', 'chapters', 'contents', 'fullContents', 'cacheInfo', 'readingProgress'];
      for (const table of tables) {
        try {
          // 先检查表是否存在，避免undefined.count()错误
          if (!db[table]) {
            console.warn(`表 ${table} 不存在或未初始化`);
            continue;
          }
          const count = await db[table].count();
          console.log(`表 ${table} 记录数: ${count}`);
        } catch (tableErr) {
          console.error(`检查表 ${table} 失败:`, tableErr);
        }
      }
      
      // 检查当前小说信息
      if (id) {
        console.log(`尝试获取小说ID=${id}的基本信息...`);
        try {
          const novelRecord = await db.novels.get(parseInt(id, 10));
          if (novelRecord) {
            console.log('数据库中的小说信息:', {
              id: novelRecord.id,
              name: novelRecord.name,
              cached: novelRecord.cached === true ? '已缓存' : novelRecord.cached === false ? '未缓存' : '未知',
              lastCached: novelRecord.lastCached ? new Date(novelRecord.lastCached).toLocaleString() : 'never'
            });
            
            // 检查是否真的有缓存内容，但不自动修复，避免状态循环
            if (novelRecord.cached || novelRecord.cached === undefined) {
              const numericId = parseInt(id, 10);
              console.log(`小说标记为已缓存或状态未知，检查是否有实际内容...`);
              
              const fullContents = await db.fullContents
                .filter(item => item.novelId == numericId)
                .toArray();
              
              if (fullContents && fullContents.length > 0) {
                const content = fullContents[0];
                console.log(`找到缓存内容: ${content.data ? '有效内容' : '无效内容'}, 长度: ${content.data ? content.data.length : 0}`);
                
                if (content.data && typeof content.data === 'string' && content.data.length > 0) {
                  console.log('缓存内容有效，可以离线阅读');
                }
              } else {
                console.warn(`未找到ID=${id}的缓存内容记录`);
              }
            }
          } else {
            console.log(`数据库中不存在ID=${id}的小说记录`);
          }
        } catch (novelErr) {
          console.error('获取小说信息失败:', novelErr);
        }
      }
      
      console.log('IndexedDB诊断完成');
      return true;
    } catch (err) {
      console.error('IndexedDB诊断过程中出错:', err);
      return false;
    }
  }, [id, hasRunDiagnosis]);
  
  // 加载小说信息和内容
  useEffect(() => {
    async function loadNovel() {
      // 防止重复加载
      if (novel && content) return;
      
      // 如果已经在加载中，取消之前的请求并返回
      if (isLoadingRef.current) {
        console.log('已有加载请求正在进行中，取消重复请求');
        if (fetchControllerRef.current) {
          try {
            fetchControllerRef.current.abort();
          } catch (e) {
            console.error('取消之前的请求失败:', e);
          }
        }
      }
      
      // 设置加载状态
      isLoadingRef.current = true;
      fetchControllerRef.current = new AbortController();
      const signal = fetchControllerRef.current.signal;
      
      try {
        setLoading(true);
        setError(null);
        
        // 检查是否是永久离线模式
        if (permanentOfflineMode) {
          console.log('永久离线模式，仅从本地加载');
          console.log(`离线模式下尝试为小说ID=${id}查询本地缓存数据`);
          
          // 在离线模式下先诊断IndexedDB状态，但只运行一次
          if (!hasRunDiagnosis) {
            await diagnoseIndexedDB();
          }
        }
        
        let novelData = null;
        let fromCache = false;
        
        try {
          // 尝试从IndexedDB中获取小说信息
          console.log(`尝试从IndexedDB中获取小说ID=${id}的信息...`);
          
          // 添加更安全的查询方式
          const numericId = parseInt(id, 10);
          const allNovels = await db.novels.toArray();
          const matchingNovel = allNovels.find(n => n.id === numericId);
          
          if (matchingNovel) {
            novelData = matchingNovel;
            console.log('从本地存储加载小说信息成功:', novelData);
            console.log(`小说名称: ${novelData.name}, 大小: ${novelData.size || 'N/A'}, 缓存状态: ${novelData.cached ? '已缓存' : '未缓存'}`);
            fromCache = true;
          } else {
            console.log(`在IndexedDB中未找到ID=${id}的小说信息`);
          }
        } catch (err) {
          console.error('从缓存获取小说信息失败:', err);
          console.log(`错误详情: ${err.message}`);
        }
        
        // 在永久离线模式下，如果没有获取到小说信息，但尝试直接获取内容，且只尝试一次
        if (!novelData && permanentOfflineMode && !hasTriedDirectLoad) {
          setHasTriedDirectLoad(true);
          console.log(`尝试直接获取ID=${id}的小说信息...`);
          try {
            // 尝试使用备选方法直接获取小说信息
            const directNovel = await novelsApi.getNovel(id);
            if (directNovel) {
              console.log(`直接获取到小说信息:`, directNovel);
              // 创建新对象而不是修改引用
              novelData = {...directNovel};
              
              // 在离线模式下尝试直接查询数据库表获取列表
              console.log('尝试获取数据库中的小说列表...');
              const allDBNovels = await db.novels.toArray();
              console.log(`数据库中有 ${allDBNovels.length} 本小说:`, allDBNovels.map(n => `ID:${n.id}, 名称:${n.name}`));
              
              // 检查是否有缓存内容
              console.log(`检查fullContents表，查询ID=${id}...`);
              const directContent = await getNovelContentDirectly(id);
              
              if (directContent) {
                // 有缓存内容但novelData不存在，可能是数据库状态不一致
                console.log(`找到完整内容，长度: ${directContent.length}，有效性: ${directContent.length > 0}`);
                console.log(`内容样本: "${directContent.substring(0, 100)}..."`);
                
                // 修复数据库状态，但不修改引用
                try {
                  console.log(`尝试修复数据库状态: 添加小说信息并标记为已缓存`);
                  // 创建包含cached属性的新对象
                  const novelToSave = {
                    ...directNovel,
                    cached: true,
                    lastCached: Date.now()
                  };
                  await db.novels.put(novelToSave);
                  // 记录已修复
                  correctedIds.add(parseInt(id, 10));
                  setHasCorrectedCache(true);
                  // 使用新对象而不是修改原始引用
                  novelData = novelToSave;
                } catch (fixErr) {
                  console.error('修复数据库状态失败:', fixErr);
                }
              } else {
                console.error(`永久离线模式下无法找到ID=${id}的缓存内容，无法继续加载`);
                setError('离线模式下无法加载未缓存的小说。请切换到在线模式后重试。');
                setLoading(false);
                return;
              }
            } else {
              console.error(`永久离线模式下无法找到ID=${id}的小说信息，无法继续加载`);
              setError('离线模式下无法加载未缓存的小说。请切换到在线模式后重试。');
              setLoading(false);
              return;
            }
          } catch (directErr) {
            console.error('尝试直接获取小说信息失败:', directErr);
            setError('离线模式下无法加载未缓存的小说。请切换到在线模式后重试。');
            setLoading(false);
            return;
          }
        }
        
        // 如果本地没有小说信息，且有网络连接，则从服务器获取
        if (!novelData && !isOffline && !permanentOfflineMode) {
          try {
            // 使用AbortController来控制请求
            const response = await fetch(`${process.env.REACT_APP_API_URL || 'http://localhost:3001/api'}/novels/${id}`, {
              signal: signal
            });
            
            if (!response.ok) {
              throw new Error(`网络请求失败: ${response.status}`);
            }
            
            novelData = await response.json();
            console.log('从服务器加载小说信息:', novelData);
            
            // 将小说信息保存到本地数据库
            if (novelData) {
              await novelOperations.addOrUpdateNovel(novelData);
            }
          } catch (apiErr) {
            // 忽略中止错误
            if (apiErr.name === 'AbortError') {
              console.log('小说信息请求被取消');
              isLoadingRef.current = false;
              return;
            }
            
            console.error('从API获取小说信息失败:', apiErr);
            
            // 网络请求失败，但仍然给用户一个友好的提示
            setError('无法从服务器加载小说信息，请检查网络连接或稍后再试');
            setLoading(false);
            isLoadingRef.current = false;
            return;
          }
        }

        // 如果无法获取小说信息，则显示错误
        if (!novelData) {
          const errorMsg = isOffline || permanentOfflineMode
            ? '离线模式下无法加载未缓存的小说'
            : '无法获取小说信息，请检查网络连接或稍后再试';
          
          setError(errorMsg);
          setLoading(false);
          return;
        }
        
        setNovel(novelData);
        
        // 获取阅读进度
        let progress = null;
        try {
          progress = await progressOperations.getProgress(id);
          
          if (progress) {
            // 设置最后阅读时间
            setLastReadTime(progress.timestamp || Date.now());
            
            // 设置阅读总进度百分比（如果有）
            if (progress.totalProgress) {
              setReadingProgress(progress.totalProgress);
            }
          }
        } catch (err) {
          console.error('获取阅读进度失败:', err);
        }
        
        // 检查小说内容是否已缓存
        let contentCached = false;
        try {
          // 检查是否已经修复过缓存状态，如果是则跳过进一步诊断
          if (hasCorrectedCache && correctedIds.has(parseInt(id, 10))) {
            console.log(`小说 ${id} 缓存状态已修复，跳过重复诊断`);
            contentCached = novelData.cached === true;
          } else {
            // 诊断缓存状态
            console.log(`开始诊断小说ID=${id}的缓存状态...`);
            const cacheDiagnosis = await diagnoseNovelStorage(id);
            console.log(`小说 ${id} 详细缓存检测结果:`, cacheDiagnosis);
            
            if (permanentOfflineMode) {
              console.log(`永久离线模式下缓存检测结果: 缓存内容${cacheDiagnosis.isContentValid ? '有效' : '无效或不存在'}`);
            }
            
            // 判断是否有有效内容 - 以实际内容存在为准，而不是仅依赖cached标记
            contentCached = cacheDiagnosis.isContentValid;
            
            // 确保novelData的cached字段与实际情况一致，但只在未修复过的情况下执行
            if (!correctedIds.has(parseInt(id, 10)) && (novelData.cached === undefined || novelData.cached !== contentCached)) {
              console.log(`小说 ${id} 的cached字段(${novelData.cached})与实际缓存状态(${contentCached})不符，进行修正`);
              
              // 更新数据库中的缓存标记以确保一致性
              if (contentCached) {
                if (novelData.cached !== true) {
                  console.log(`小说 ${id} 有内容但未标记为缓存，更新标记...`);
                  await db.novels.update(id, { cached: true });
                  
                  // 创建新对象而不是修改引用
                  novelData = { ...novelData, cached: true };
                  
                  // 记录已修复
                  correctedIds.add(parseInt(id, 10));
                  setHasCorrectedCache(true);
                }
                console.log(`确认小说 ${id} 已正确缓存，大小: ${cacheDiagnosis.fullContentLength} 字节`);
              } else {
                if (novelData.cached === true) {
                  console.warn(`小说 ${id} 被标记为已缓存，但内容无效或不存在，修复标记...`);
                  await db.novels.update(id, { cached: false });
                  
                  // 创建新对象而不是修改引用
                  novelData = { ...novelData, cached: false };
                  
                  // 记录已修复
                  correctedIds.add(parseInt(id, 10));
                  setHasCorrectedCache(true);
                }
                console.log(`小说 ${id} 未缓存或内容无效`);
              }
            }
          }
          
          setIsCached(contentCached);
          console.log(`小说缓存状态检查结果: ${contentCached ? '已缓存且有效' : '未缓存或缓存无效'}`);
        } catch (err) {
          console.error('检查内容缓存失败:', err);
          console.log(`缓存检查错误详情: ${err.message}`);
          contentCached = false;
          setIsCached(false);
        }
        
        // 在永久离线模式下，如果内容未缓存但有直接获取的内容，尝试加载
        if (!contentCached && permanentOfflineMode) {
          console.log(`永久离线模式下小说未缓存，尝试直接获取内容...`);
          const directContent = await getNovelContentDirectly(id);
          
          if (directContent) {
            console.log(`成功直接获取到内容，长度: ${directContent.length}，尝试加载`);
            await processContent(directContent, novelData, progress);
            setLoading(false);
            return;
          } else {
            console.error(`永久离线模式下小说ID=${id}的内容未缓存或缓存无效，无法继续加载`);
            setError(`离线模式下无法阅读未缓存的小说《${novelData.name}》。请开启网络连接后重试。`);
            setLoading(false);
            return;
          }
        }
        
        // 根据缓存状态和网络状态决定如何加载内容
        if (contentCached) {
          try {
            console.log('从本地缓存加载内容');
            console.log(`开始查询 novelId=${id} 的缓存内容`);
            
            // 记录离线状态
            if (isOffline || permanentOfflineMode) {
              console.log(`当前处于${permanentOfflineMode ? '永久' : ''}离线模式，只从缓存读取数据`);
              if (permanentOfflineMode) {
                console.log(`永久离线模式：开始从IndexedDB的fullContents表查询novelId=${id}的完整内容`);
              }
            }
            
            safeConsoleTime('从缓存加载内容耗时');
            const cachedContent = await novelOperations.getNovelContent(id);
            try {
              console.timeEnd('从缓存加载内容耗时');
            } catch (e) {
              // 忽略错误
            }
            
            if (cachedContent && cachedContent.length > 0) {
              console.log(`缓存内容获取成功，内容长度: ${cachedContent.length}`);
              console.log(`缓存内容前50个字符: "${cachedContent.substring(0, 50)}..."`);
              
              if (permanentOfflineMode) {
                console.log('永久离线模式：缓存内容验证成功，准备处理内容和章节');
              }
              
              // 处理内容
              console.log(`开始处理缓存内容和解析章节...`);
              await processContent(cachedContent, novelData, progress);
              console.log(`缓存内容处理完成，小说加载成功`);
              setLoading(false);
              return;
            } else {
              console.warn('缓存内容为空或损坏');
              
              if (permanentOfflineMode) {
                console.error('永久离线模式：缓存内容返回为空，无法加载小说');
              }
              
              // 如果在离线模式下发现缓存无效
              if (isOffline || permanentOfflineMode) {
                console.error('离线模式下缓存内容无效，无法继续加载');
                setError('离线模式下缓存内容损坏或为空，无法加载。请在有网络连接时重新缓存。');
                setLoading(false);
                return;
              }
            }
          } catch (err) {
            console.error('从缓存加载内容失败:', err);
            console.log('尝试分析缓存问题:', {
              错误类型: err.name,
              错误信息: err.message,
              缓存ID: id,
              离线状态: isOffline || permanentOfflineMode ? '离线' : '在线'
            });
            
            if (permanentOfflineMode) {
              console.error(`永久离线模式：缓存访问出错 - ${err.name}: ${err.message}`);
              console.error('请检查IndexedDB是否可用，或尝试清除浏览器缓存后重试');
            }
            
            // 如果在离线模式下，提示用户
            if (isOffline || permanentOfflineMode) {
              setError(`缓存内容加载失败：${err.message}。请在有网络连接时重新缓存。`);
              setLoading(false);
              return;
            }
          }
        } else {
          console.log(`小说 ${id} 未被缓存或缓存标记不正确`);
          if (isOffline || permanentOfflineMode) {
            console.error('离线模式下无法加载未缓存的小说');
            if (permanentOfflineMode) {
              console.error(`永久离线模式：小说ID=${id}未被缓存，无法加载。请切换到在线模式并缓存此小说。`);
            }
          }
        }
        
        // 如果缓存不可用或加载失败，且不在离线模式，则从服务器加载
        if (!isOffline && !permanentOfflineMode) {
          console.log('从服务器加载内容');
          try {
            await loadContentFromServer(novelData, progress);
          } catch (contentErr) {
            // 忽略中止错误
            if (contentErr.name === 'AbortError') {
              console.log('内容加载请求被取消');
              isLoadingRef.current = false;
              return;
            }
            
            setError(`无法加载《${novelData.name}》: ${contentErr.message || '加载小说内容时出错'}`);
            setLoading(false);
            isLoadingRef.current = false;
            return;
          }
        } else {
          // 如果没有缓存且在离线模式下
          setError(`离线模式下无法阅读未缓存的小说《${novelData.name}》。请开启网络连接后重试。`);
          setLoading(false);
          return;
        }
      } catch (err) {
        // 忽略中止错误
        if (err.name === 'AbortError') {
          console.log('请求被取消');
          isLoadingRef.current = false;
          return;
        }
        
        console.error('加载小说失败:', err);
        
        let errorMessage = '加载小说失败，';
        
        if (isOffline || permanentOfflineMode) {
          errorMessage += '您当前处于离线模式，无法加载未缓存的小说。';
        } else if (err.message && err.message.includes('fetch')) {
          errorMessage += '网络请求失败，请检查您的网络连接。';
        } else {
          errorMessage += err.message || '请稍后重试。';
        }
        
        setError(errorMessage);
        setLoading(false);
      } finally {
        isLoadingRef.current = false;
      }
    }
    
    if (id) {
      loadNovel();
    }
    
    // 组件卸载时取消所有未完成的请求
    return () => {
      if (fetchControllerRef.current) {
        try {
          fetchControllerRef.current.abort();
          console.log('组件卸载，取消所有未完成的请求');
        } catch (e) {
          console.error('取消请求失败:', e);
        }
      }
      isLoadingRef.current = false;
    };
  }, [id, isOffline, permanentOfflineMode]); // 减少依赖项，只保留必要的
  
  // 预加载相邻章节
  useEffect(() => {
    if (!currentChapter || !content || chapters.length <= 1) return;
    
    // 确定当前章节索引
    const currentIndex = chapters.findIndex(ch => ch.id === currentChapter.id);
    if (currentIndex === -1) return;
    
    // 函数：预加载指定章节的内容到缓存中
    const preloadChapter = (chapter) => {
      if (!chapter) return;
      
      // 获取章节内容
      const chapterContent = content.substring(chapter.position, chapter.endPosition);
      
      // 使用一个简单的缓存机制，使用Map或对象来存储预加载的章节内容
      // 这里使用sessionStorage作为简单的示例，实际可以使用内存缓存
      try {
        // 将chapter标题和内容存入sessionStorage
        sessionStorage.setItem(`chapter_${chapter.id}`, JSON.stringify({
          title: chapter.title,
          content: chapterContent,
          timestamp: Date.now()
        }));
        
        console.log(`已预加载章节: ${chapter.title}  检测到脱机之后添加更多的log`);
      } catch (e) {
        // sessionStorage可能因为容量限制而失败
        console.error('预加载章节内容失败:', e);
      }
    };
    
    // 预加载下一章（如果存在）
    if (currentIndex < chapters.length - 1) {
      const nextChapter = chapters[currentIndex + 1];
      preloadChapter(nextChapter);
    }
    
    // 预加载上一章（优先级较低，因此放在setTimeout中）
    if (currentIndex > 0) {
      setTimeout(() => {
        const prevChapter = chapters[currentIndex - 1];
        preloadChapter(prevChapter);
      }, 1000);  // 延迟1秒加载上一章
    }
  }, [currentChapter, chapters, content]);
  
  // 处理滚动事件以自动保存阅读位置 - 修复useDebounce的使用
  useEffect(() => {
    if (!contentRef.current || !currentChapter || !id || !chapters.length) return;
    
    // 使用常规的防抖函数，不用hook
    const debouncedSavePosition = debounce(() => {
      saveReadingPosition();
    }, 500);
    
    const handleScroll = () => {
      debouncedSavePosition();
    };
    
    const contentElement = contentRef.current;
    contentElement.addEventListener('scroll', handleScroll);
    
    return () => {
      contentElement.removeEventListener('scroll', handleScroll);
    };
  }, [contentRef, currentChapter, id, chapters.length, saveReadingPosition]);
  
  // 从服务器加载小说内容
  const loadContentFromServer = async (novelData, progress) => {
    try {
      setLoadingText('正在从服务器获取小说内容...');
      
      // 确保当前请求可以被取消
      if (!fetchControllerRef.current) {
        fetchControllerRef.current = new AbortController();
      }
      const signal = fetchControllerRef.current.signal;
      
      // 获取完整内容，传递当前编码设置 (如果不是auto，则使用指定编码)
      console.log(`尝试获取小说内容: ${id}${settings.encoding !== 'auto' ? `, 强制编码: ${settings.encoding}` : ''}`);
      
      // 直接使用fetch代替api调用，以便使用AbortController
      const encodingParam = settings.encoding !== 'auto' ? `?encoding=${settings.encoding}` : '';
      const apiUrl = `${process.env.REACT_APP_API_URL || 'http://localhost:3001/api'}/novels/${id}/content${encodingParam}`;
      
      console.log(`发起请求: ${apiUrl}`);
      const response = await fetch(apiUrl, { signal });
      
      if (!response.ok) {
        throw new Error(`获取小说内容失败 (状态码: ${response.status})`);
      }
      
      const result = await response.json();
      
      let allContent = '';
      if (result && result.content) {
        allContent = result.content;
        console.log(`成功获取小说内容，长度: ${allContent.length}, 服务器编码: ${result.encoding}`);
      } else {
        throw new Error('获取小说内容格式不正确');
      }
      
      // 缓存内容到本地
      try {
        console.log(`缓存小说 "${novelData.name}" 内容到本地`);
        await novelOperations.cacheNovel(novelData, allContent);
        setIsCached(true);
        console.log(`小说 "${novelData.name}" 缓存完成`);
      } catch (cacheErr) {
        console.error('缓存小说失败，但可以继续阅读:', cacheErr);
        setIsCached(false);
      }
      
      // 处理内容和章节
      await processContent(allContent, novelData, progress);
      
      return allContent;
    } catch (err) {
      // 中止错误单独处理
      if (err.name === 'AbortError') {
        console.log('内容获取请求被取消');
        throw err; // 重新抛出中止错误，让调用者处理
      }
      
      console.error('从服务器加载内容失败:', err);
      throw err;
    }
  };

  // 在处理内容和console.time前添加检查，避免重复调用
  const consoleTimeExists = {};
  const safeConsoleTime = (label) => {
    // 如果已存在相同label的timer，先结束它
    if (consoleTimeExists[label]) {
      try {
        console.timeEnd(label);
      } catch (e) {
        // 忽略错误
      }
    }
    // 标记这个label已经被使用
    consoleTimeExists[label] = true;
    console.time(label);
  };

  // 添加缺失的processContent函数
  const processContent = async (content, novelData, progress) => {
    try {
      if (!content) {
        throw new Error('内容为空');
      }
      
      console.log(`开始处理小说内容，长度: ${content.length}`);
      setLoading(true);
      setLoadingText('正在解析章节...');
      
      // 保存小说信息
      setNovel(novelData);
      
      // 保存原始内容
      setContent(content);
      
      // 解析章节，使用设置中的最大章节长度
      const maxChars = settings.maxChapterChars || 10000;
      console.log(`使用最大章节长度: ${maxChars}字符`);
      safeConsoleTime('解析章节耗时');
      
      // 注意: 对大型小说，parseChapters可能会很耗时
      // 使用setTimeout将其移到下一个事件循环，让UI可以先更新
      setTimeout(async () => {
        try {
          // 创建Web Worker处理章节解析（如果支持）
          let parsedChapters;
          
          try {
            console.log('开始解析章节...');
            parsedChapters = await parseChapters(content, maxChars);
            console.log(`章节解析完成，共 ${parsedChapters.length} 章`);
          } catch (parseErr) {
            console.error('解析章节失败:', parseErr);
            throw new Error(`解析章节失败: ${parseErr.message}`);
          }
          
          // 对于特别多的章节，进行分批处理以避免UI卡顿
          if (parsedChapters.length > 500) {
            setLoadingText(`正在处理${parsedChapters.length}个章节...`);
            
            // 首先设置章节基本信息，使界面可以先显示
            setChapters(parsedChapters);
            
            // 如果有阅读进度，加载对应章节
            if (progress && progress.chapterId) {
              const savedChapter = parsedChapters.find(ch => ch.id === progress.chapterId);
              if (savedChapter) {
                console.log(`找到保存的阅读进度，章节: ${savedChapter.title}`);
                
                // 设置当前章节并加载
                loadSavedChapter(content, savedChapter, progress.position);
                
                // 显示"继续阅读"提示
                setLastReadTime(progress.timestamp);
                setReadingProgress(progress.progress || 0);
                setShowContinueReading(true);
                
              } else {
                // 找不到保存的章节，加载第一章
                console.log('未找到保存的章节，加载第一章');
                loadFirstChapter(content, parsedChapters);
              }
            } else {
              // 没有进度记录，加载第一章
              console.log('无阅读进度记录，加载第一章');
              loadFirstChapter(content, parsedChapters);
            }
          } else {
            // 章节数量不多，直接处理
            setChapters(parsedChapters);
            
            if (progress && progress.chapterId) {
              const savedChapter = parsedChapters.find(ch => ch.id === progress.chapterId);
              if (savedChapter) {
                loadSavedChapter(content, savedChapter, progress.position);
                setLastReadTime(progress.timestamp);
                setReadingProgress(progress.progress || 0);
                setShowContinueReading(true);
              } else {
                loadFirstChapter(content, parsedChapters);
              }
            } else {
              loadFirstChapter(content, parsedChapters);
            }
          }
          
          // 记录缓存状态
          if (novelData.id) {
            const hasCache = await db.novels.get(parseInt(novelData.id, 10));
            setIsCached(hasCache && hasCache.cached);
          }
          
          try {
            console.timeEnd('解析章节耗时');
          } catch (e) {
            // 忽略错误
          }
          setLoading(false);
          
        } catch (err) {
          console.error('处理内容失败:', err);
          setError(`处理内容失败: ${err.message}`);
          setLoading(false);
        }
      }, 50); // 短暂延迟，让UI可以更新
      
    } catch (err) {
      console.error('处理内容时出错:', err);
      setError(`处理内容失败: ${err.message}`);
      setLoading(false);
    }
  };
  
  // 加载第一章
  const loadFirstChapter = (content, chapters) => {
    if (chapters.length > 0) {
      console.log(`加载第一章: ${chapters[0].title}`);
      setCurrentChapter(chapters[0]);
      
      // 获取章节内容
      const chContent = content.substring(chapters[0].position, chapters[0].endPosition);
      setChapterContent(chContent);
      setReadingPosition(0);
      
      // 分割段落并过滤空行
      const parts = chContent.split('\n')
        .map(p => p.trim())
        .filter(p => p.length > 0);
      setParagraphs(parts);
    }
  };
  
  // 加载保存的章节和位置
  const loadSavedChapter = (content, chapter, position) => {
    console.log(`加载保存的章节: ${chapter.title}, 位置: ${position}`);
    setCurrentChapter(chapter);
    
    // 获取章节内容
    const chContent = content.substring(chapter.position, chapter.endPosition);
    setChapterContent(chContent);
    setReadingPosition(position);
    
    // 分割段落并过滤空行
    const parts = chContent.split('\n')
      .map(p => p.trim())
      .filter(p => p.length > 0);
    setParagraphs(parts);
    
    // 恢复阅读位置
    if (position > 0 && contentRef.current) {
      setTimeout(() => {
        if (contentRef.current) {
          contentRef.current.scrollTo(0, position);
        }
      }, 100);
    }
  };
  
  // 切换章节
  const handleChapterChange = (chapter) => {
    if (!chapter) return;
    
    setCurrentChapter(chapter);
    
    // 获取章节内容
    try {
      const chContent = content.substring(chapter.position, chapter.endPosition);
      setChapterContent(chContent);
      setReadingPosition(0);
      
      // 分割段落并过滤空行
      const parts = chContent.split('\n')
        .map(p => p.trim())
        .filter(p => p.length > 0);
      setParagraphs(parts);
    } catch (err) {
      console.error('切换章节获取内容失败:', err);
      setParagraphs(['获取章节内容失败']);
    }
    
    // 计算阅读总进度
    const chapterIndex = chapters.findIndex(ch => ch.id === chapter.id);
    const totalProgress = ((chapterIndex / chapters.length) * 100);
    const formattedProgress = totalProgress.toFixed(1);
    
    // 保存阅读进度，包含时间戳和总进度
    progressOperations.saveProgress(id, chapter.id, 0, Date.now(), formattedProgress);
    
    // 更新组件状态
    setLastReadTime(Date.now());
    setReadingProgress(parseFloat(formattedProgress));
    
    // 在移动设备上自动隐藏侧边栏
    if (window.innerWidth < 768) {
      setShowSidebar(false);
    }
  };
  
  // 处理继续阅读
  const handleContinueReading = () => {
    setShowContinueReading(false);
  };
  
  // 下一章
  const handleNextChapter = useCallback(() => {
    if (!currentChapter || chapters.length === 0) return;
    
    const currentIndex = chapters.findIndex(ch => ch.id === currentChapter.id);
    if (currentIndex < chapters.length - 1) {
      handleChapterChange(chapters[currentIndex + 1]);
    }
  }, [currentChapter, chapters]);
  
  // 上一章
  const handlePrevChapter = useCallback(() => {
    if (!currentChapter || chapters.length === 0) return;
    
    const currentIndex = chapters.findIndex(ch => ch.id === currentChapter.id);
    if (currentIndex > 0) {
      handleChapterChange(chapters[currentIndex - 1]);
    }
  }, [currentChapter, chapters]);
  
  // 更新设置
  const updateSettings = (key, value) => {
    const newSettings = { ...settings, [key]: value };
    setSettings(newSettings);
    localStorage.setItem('reader-settings', JSON.stringify(newSettings));
  };
  
  // 切换主题
  const toggleTheme = () => {
    const newTheme = settings.theme === 'light' ? 'dark' : settings.theme === 'dark' ? 'sepia' : 'light';
    updateSettings('theme', newTheme);
  };
  
  // 获取基于当前主题的样式
  const getThemeStyles = () => {
    switch (settings.theme) {
      case 'dark':
        return {
          bgColor: 'bg-reader-night',
          textColor: 'text-gray-200',
          sidebarBg: 'bg-gray-900',
          headerBg: 'bg-gray-800',
          buttonHover: 'hover:bg-gray-700',
          buttonBg: 'bg-gray-700',
          selectBg: 'bg-gray-700 text-white',
        };
      case 'sepia':
        return {
          bgColor: 'bg-reader-cream',
          textColor: 'text-reader-ink',
          sidebarBg: 'bg-yellow-50',
          headerBg: 'bg-yellow-100',
          buttonHover: 'hover:bg-yellow-200',
          buttonBg: 'bg-yellow-200',
          selectBg: 'bg-yellow-100',
        };
      default: // light
        return {
          bgColor: 'bg-reader-paper',
          textColor: 'text-reader-ink',
          sidebarBg: 'bg-white',
          headerBg: 'bg-white',
          buttonHover: 'hover:bg-gray-100',
          buttonBg: 'bg-gray-100',
          selectBg: 'bg-white',
        };
    }
  };
  
  const theme = getThemeStyles();
  
  // 格式化日期
  const formatDate = (timestamp) => {
    if (!timestamp) return '';
    
    const date = new Date(timestamp);
    const now = new Date();
    const isToday = date.toDateString() === now.toDateString();
    const isYesterday = new Date(now - 86400000).toDateString() === date.toDateString();
    
    if (isToday) {
      return `今天 ${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`;
    } else if (isYesterday) {
      return `昨天 ${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`;
    } else {
      return `${date.getMonth() + 1}月${date.getDate()}日 ${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`;
    }
  };
  
  // 计算当前应该显示的章节列表 - 仅在不使用虚拟滚动时使用
  const visibleChapters = useMemo(() => {
    if (!chapters || chapters.length === 0) return [];
    
    // 如果章节总数少于显示数量，直接返回全部章节
    if (chapters.length <= visibleChaptersCount) return chapters;
    
    // 否则返回可见范围内的章节
    return chapters.slice(visibleChaptersStart, visibleChaptersStart + visibleChaptersCount);
  }, [chapters, visibleChaptersStart, visibleChaptersCount]);
  
  // 加载更多章节
  const loadMoreChapters = useCallback(() => {
    // 如果已经展示了全部章节，直接返回
    if (chapters.length <= visibleChaptersStart + visibleChaptersCount) return;
    
    // 增加显示的章节数量
    setVisibleChaptersCount(prevCount => prevCount + 300);
  }, [chapters, visibleChaptersStart, visibleChaptersCount]);

  // 跳转到指定章节区域
  const jumpToChapterSection = useCallback((sectionIndex) => {
    if (!chapters || chapters.length === 0) return;
    
    // 计算需要跳转的位置
    const sectionSize = 300; // 每个区块的大小
    const targetStart = sectionIndex * sectionSize;
    
    // 确保不超出边界
    if (targetStart < chapters.length) {
      setVisibleChaptersStart(targetStart);
      setVisibleChaptersCount(300);
    }
  }, [chapters]);
  
  // 添加缺失的handleRepairCache函数
  const handleRepairCache = useCallback(async () => {
    try {
      setLoading(true);
      setError(null);
      
      console.log('开始自动修复缓存...');
      
      // 重置缓存状态
      if (novel && novel.id) {
        await db.novels.update(novel.id, { cached: false });
        
        // 如果在离线模式且有网络，尝试切换到在线模式
        if (permanentOfflineMode && navigator.onLine) {
          setPermanentOfflineMode(false);
          localStorage.setItem('offlineMode', 'false');
        }
        
        if (navigator.onLine) {
          // 如果有网络连接，尝试从服务器重新获取
          try {
            const refreshedNovelData = await novelsApi.getNovel(id);
            if (refreshedNovelData) {
              // 更新本地数据
              await novelOperations.addOrUpdateNovel(refreshedNovelData);
              
              // 获取内容并重新缓存
              const contentResponse = await novelsApi.getFullNovelContent(id);
              if (contentResponse && contentResponse.content) {
                await novelOperations.cacheNovel(refreshedNovelData, contentResponse.content);
                
                // 验证缓存是否成功
                const verifyDiag = await diagnoseNovelStorage(id);
                if (verifyDiag.isContentValid) {
                  // 重新加载小说
                  window.location.reload();
                  return;
                } else {
                  throw new Error('缓存验证失败');
                }
              } else {
                throw new Error('获取内容失败');
              }
            } else {
              throw new Error('获取小说信息失败');
            }
          } catch (fetchErr) {
            console.error('从服务器重新获取失败:', fetchErr);
            setError(`修复失败: ${fetchErr.message}`);
            setLoading(false);
          }
        } else {
          setError('无法修复: 当前无网络连接');
          setLoading(false);
        }
      } else {
        setError('无法修复: 缺少小说信息');
        setLoading(false);
      }
    } catch (err) {
      console.error('修复缓存失败:', err);
      setError(`修复失败: ${err.message}`);
      setLoading(false);
    }
  }, [diagnoseNovelStorage, id, novel, permanentOfflineMode, navigator.onLine, setLoading, setError, setPermanentOfflineMode]);
  
  // 解析章节的函数实现
  const parseChapters = useCallback(async (content, maxChars) => {
    console.log(`开始解析章节，内容长度: ${content.length}, 最大章节长度: ${maxChars}`);
    
    try {
      return splitContentIntoChunks(content, maxChars);
    } catch (err) {
      console.error("解析章节失败:", err);
      throw err;
    }
  }, []);
  
  // 修改页面标题
  useEffect(() => {
    if (novel) {
      document.title = `${novel.name} - 阅读中`;
    } else {
      document.title = '小说阅读器';
    }
    return () => {
      document.title = '小说阅读器';
    };
  }, [novel]);
  
  if (loading) {
    return <div className="container mx-auto p-4 text-center">正在加载: {loadingText || '准备中...'}</div>;
  }
  
  if (error) {
    let is404Error = error.includes('404') || error.includes('无法获取小说信息') || error.includes('不存在');
    // 检测是否是缓存问题
    let isCacheError = error.includes('缓存') || error.includes('离线模式');
    let offlineMode = isOffline || permanentOfflineMode;
    
    // 判断是否可以修复
    const canRepairCache = novel && novel.id && error.includes('缓存');
    
    return (
      <div className="container mx-auto p-4 text-center">
        <div className="bg-white rounded-lg shadow-md p-6 max-w-2xl mx-auto dark:bg-gray-800">
          <h2 className="text-xl font-bold text-red-500 mb-4">加载失败</h2>
          <p className="text-gray-700 dark:text-gray-300 whitespace-pre-line mb-4">{error}</p>
          
          {is404Error && (
            <div className="mb-4 p-3 bg-yellow-50 border border-yellow-200 rounded-md dark:bg-yellow-900 dark:border-yellow-800">
              <p className="text-sm text-yellow-700 dark:text-yellow-300">
                此小说可能在服务器上已不存在。您可以返回书架并使用"修复数据库"功能清理无效记录。
              </p>
            </div>
          )}
          
          {isCacheError && offlineMode && (
            <div className="mb-4 p-3 bg-yellow-50 border border-yellow-200 rounded-md dark:bg-yellow-900 dark:border-yellow-800">
              <p className="text-sm text-yellow-700 dark:text-yellow-300">
                您正处于离线模式，但小说缓存数据无效或已损坏。请切换回在线模式并重新缓存此小说。
              </p>
            </div>
          )}
          
          <div className="flex flex-col md:flex-row gap-3 justify-center">
            <button 
              className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
              onClick={returnToBookshelf}
            >
              返回书架
            </button>
            
            {is404Error && (
              <button 
                className="bg-yellow-500 hover:bg-yellow-600 text-white font-bold py-2 px-4 rounded"
                onClick={() => {
                  navigate('/', { state: { openRepairDialog: true, invalidNovelId: id } });
                }}
              >
                修复数据库
              </button>
            )}
            
            {isCacheError && offlineMode && (
              <button 
                className="bg-green-500 hover:bg-green-600 text-white font-bold py-2 px-4 rounded"
                onClick={() => {
                  // 切换回在线模式并刷新
                  setPermanentOfflineMode(false);
                  localStorage.setItem('offlineMode', 'false');
                  window.location.reload();
                }}
              >
                切换为在线模式
              </button>
            )}
            
            {canRepairCache && (
              <button 
                className="bg-purple-500 hover:bg-purple-600 text-white font-bold py-2 px-4 rounded"
                onClick={handleRepairCache}
              >
                {loading ? '修复中...' : '自动修复'}
              </button>
            )}
          </div>
        </div>
      </div>
    );
  }
  
  return (
    <div className={`flex flex-col h-screen ${theme.bgColor} ${theme.textColor}`}>
      {/* 顶部导航栏 */}
      <header className={`px-2 py-3 flex items-center justify-between shadow-sm ${theme.headerBg} border-b border-gray-200 dark:border-gray-800`}>
        {/* 返回按钮 */}
        <div className="flex items-center">
          <button 
            className="p-3 rounded-full hover:bg-gray-200 dark:hover:bg-gray-700 flex items-center"
            onClick={returnToBookshelf}
            aria-label="返回书架"
          >
            <FiChevronLeft size={22} />
            <span className="ml-1 hidden sm:inline">返回</span>
          </button>
          <div className="ml-1 flex flex-col truncate max-w-[150px] sm:max-w-xs">
            <h1 className="text-base sm:text-lg font-bold truncate">{novel?.name || '加载中...'}</h1>
            <div className="text-xs text-gray-500 flex items-center">
              <span className="mr-1">{typeof readingProgress === 'number' ? `${readingProgress.toFixed(1)}%` : '0%'}</span>
              {isCached && (
                <span className="ml-2 flex items-center text-green-500">
                  <FiDownload size={12} className="mr-1" />
                  <span className="hidden sm:inline">已缓存</span>
                </span>
              )}
            </div>
          </div>
        </div>
        
        {/* 右侧操作按钮 - 在移动端隐藏部分 */}
        <div className="flex items-center space-x-1">
          {/* 缓存按钮 - 仅非离线模式显示 */}
          {!isCached && !isOffline && !permanentOfflineMode && (
            <button 
              className={`p-2 sm:p-3 rounded-full ${isCaching ? 'text-blue-600 animate-pulse' : 'hover:bg-gray-200 dark:hover:bg-gray-700'} hidden sm:block`}
              onClick={handleCacheNovel}
              disabled={isCaching}
              aria-label="缓存小说"
              title="缓存小说以便离线阅读"
            >
              {isCaching ? (
                <span className="flex items-center">
                  <FiDownload className="animate-bounce" />
                  <span className="ml-1 text-xs">{cacheProgress}%</span>
                </span>
              ) : (
                <FiDownload />
              )}
            </button>
          )}
          
          {/* 章节列表切换 - 中小屏使用底部导航代替 */}
          <button
            className="p-2 sm:p-3 rounded-full hover:bg-gray-200 dark:hover:bg-gray-700 md:hidden"
            onClick={() => setShowSidebar(!showSidebar)}
            aria-label="章节目录"
          >
            <FiMenu />
          </button>
          
          {/* 设置按钮 - 中小屏使用底部导航代替 */}
          <button
            className="p-2 sm:p-3 rounded-full hover:bg-gray-200 dark:hover:bg-gray-700 hidden md:block"
            onClick={() => setShowSettings(!showSettings)}
            aria-label="阅读设置"
          >
            <FiSettings />
          </button>
        </div>
      </header>

      {/* 阅读进度指示器 */}
      <div 
        className="h-0.5 bg-gray-200 dark:bg-gray-700 relative"
        title={`阅读进度: ${typeof readingProgress === 'number' ? readingProgress.toFixed(1) : 0}%`}
      >
        <div 
          className="h-full bg-blue-500" 
          style={{ width: `${typeof readingProgress === 'number' ? readingProgress : 0}%` }}
        ></div>
      </div>
      
      {/* 继续阅读按钮 */}
      {showContinueReading && (
        <div className="fixed bottom-4 left-1/2 transform -translate-x-1/2 z-20 bg-white dark:bg-gray-800 rounded-lg shadow-lg p-3 flex items-center justify-between w-11/12 sm:w-auto mx-auto max-w-md">
          <div className="flex items-center">
            <FiBookOpen className="mr-2 flex-shrink-0" />
            <div>
              <p className="text-sm font-semibold">继续阅读</p>
              <p className="text-xs opacity-70">上次阅读：{formatDate(lastReadTime)} · {currentChapter.title}</p>
            </div>
          </div>
          <button 
            className="px-3 py-1 bg-blue-500 text-white rounded text-sm"
            onClick={handleContinueReading}
          >
            继续
          </button>
        </div>
      )}
      
      <div className="flex flex-1 overflow-hidden">
        {/* 侧边栏 - 章节列表 */}
        <div 
          className={`${theme.sidebarBg} shadow-md fixed md:relative z-10 h-full transition-all duration-300 w-4/5 sm:w-72 md:w-64 transform ${showSidebar ? 'translate-x-0' : '-translate-x-full md:translate-x-0'} flex flex-col`}
        >
          <div className={`p-2 font-semibold text-center border-b ${theme.headerBg} flex justify-between items-center`}>
            <span>目录 ({chapters.length}章)</span>
            <button 
              className="md:hidden p-2 rounded-full hover:bg-gray-200 dark:hover:bg-gray-700"
              onClick={() => setShowSidebar(false)}
            >
              <FiX size={20} />
            </button>
          </div>
          
          {/* 章节区块跳转 */}
          {chapters.length > 1000 && (
            <div className="p-2 border-b">
              <p className="text-xs text-gray-500 mb-1">章节过多，选择区块：</p>
              <div className="flex flex-wrap gap-1">
                {Array.from({ length: Math.ceil(chapters.length / 300) }).map((_, idx) => (
                  <button
                    key={`block-${idx}`}
                    onClick={() => jumpToChapterSection(idx)}
                    className="px-1 py-0.5 text-xs bg-gray-100 dark:bg-gray-700 rounded hover:bg-gray-200 dark:hover:bg-gray-600"
                  >
                    {idx + 1}
                  </button>
                ))}
              </div>
            </div>
          )}
          
          {/* 使用虚拟滚动组件代替原来的章节列表渲染 */}
          {chapters.length > 500 ? (
            <ChapterVirtualList 
              chapters={chapters} 
              onSelect={handleChapterChange} 
              currentChapterId={currentChapter?.id}
              theme={theme}
            />
          ) : (
            <div className="overflow-y-auto flex-1">
              {visibleChapters.map((chapter) => (
                <div 
                  key={chapter.id}
                  className={`p-3 ${theme.buttonHover} cursor-pointer flex items-center justify-between 
                    ${currentChapter?.id === chapter.id ? 'bg-blue-100 dark:bg-blue-900' : ''} 
                    border-b border-gray-100 dark:border-gray-800`}
                  onClick={() => handleChapterChange(chapter)}
                >
                  <div className="flex-1 truncate text-sm">
                    {chapter.title}
                  </div>
                  {/* 当前阅读的章节显示标记 */}
                  {currentChapter?.id === chapter.id && (
                    <div className="w-2 h-2 rounded-full bg-blue-500 ml-2 flex-shrink-0"></div>
                  )}
                </div>
              ))}
              
              {/* 如果还有更多章节，显示加载更多按钮 - 仅在非虚拟滚动模式下显示 */}
              {chapters.length > visibleChaptersStart + visibleChaptersCount && (
                <div className="p-2 text-center">
                  <button
                    onClick={loadMoreChapters}
                    className="w-full px-2 py-1 text-sm bg-blue-500 text-white rounded hover:bg-blue-600"
                  >
                    加载更多章节
                  </button>
                </div>
              )}
            </div>
          )}
        </div>
        
        {/* 内容区 */}
        <div className={`flex-1 overflow-auto h-full ${theme.bgColor} ${theme.textColor}`} ref={contentRef}>
          <div className="max-w-3xl mx-auto px-4 sm:px-6 py-16 sm:py-20 pb-24 md:pb-16">
            {/* 当前章节标题 */}
            <h1 className="text-xl sm:text-2xl font-semibold mb-6 text-center">
              {currentChapter?.title || novel?.name}
            </h1>
            
            {/* 章节内容 */}
            <div 
              className="leading-relaxed text-base sm:text-lg"
              style={{ 
                fontSize: `${settings.fontSize}px`, 
                lineHeight: settings.lineHeight,
                fontFamily: settings.fontFamily === 'default' ? '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif' :
                           settings.fontFamily === 'serif' ? 'Georgia, "Times New Roman", serif' :
                           settings.fontFamily === 'mono' ? 'SFMono-Regular, Menlo, Monaco, monospace' : 
                           'Kai, "Kaiti SC", STKaiti, "AR PL UKai CN", "AR PL UKai HK", "AR PL UKai TW", "AR PL UKai TW MBE", "AR PL KaitiM GB", KaiTi, KaiTi_GB2312, "TW-Kai", serif'
              }}
            >
              {paragraphs.map((paragraph, index) => (
                <p key={index} className="mb-4 sm:mb-5">
                  {paragraph}
                </p>
              ))}
            </div>
            
            {/* 章节导航按钮 */}
            <div className="flex justify-between mt-8 pt-4 border-t">
              <button 
                onClick={handlePrevChapter}
                className={`px-4 py-2 rounded ${theme.buttonBg} ${theme.buttonHover} ${chapters.findIndex(ch => ch.id === currentChapter?.id) <= 0 ? 'opacity-50 cursor-not-allowed' : ''}`}
                disabled={chapters.findIndex(ch => ch.id === currentChapter?.id) <= 0}
              >
                上一章
              </button>
              <button 
                onClick={handleNextChapter}
                className={`px-4 py-2 rounded ${theme.buttonBg} ${theme.buttonHover} ${chapters.findIndex(ch => ch.id === currentChapter?.id) >= chapters.length - 1 ? 'opacity-50 cursor-not-allowed' : ''}`}
                disabled={chapters.findIndex(ch => ch.id === currentChapter?.id) >= chapters.length - 1}
              >
                下一章
              </button>
            </div>
          </div>
        </div>
      </div>
      
      {/* 添加底部操作栏 - 在移动端更易于操作 */}
      <div className={`fixed bottom-0 left-0 right-0 ${theme.headerBg} shadow-lg border-t border-gray-200 dark:border-gray-700 p-2 flex justify-around z-10 md:hidden pb-safe`}>
        <button
          className="p-3 rounded-full hover:bg-gray-200 dark:hover:bg-gray-700 flex flex-col items-center"
          onClick={() => setShowSidebar(!showSidebar)}
        >
          <FiList size={20} />
          <span className="text-xs mt-1">目录</span>
        </button>
        
        <button
          className="p-3 rounded-full hover:bg-gray-200 dark:hover:bg-gray-700 flex flex-col items-center"
          onClick={() => updateSettings('fontSize', Math.max(settings.fontSize - 2, 14))}
        >
          <FiMinus size={20} />
          <span className="text-xs mt-1">字体</span>
        </button>
        
        <button
          className="p-3 rounded-full hover:bg-gray-200 dark:hover:bg-gray-700 flex flex-col items-center"
          onClick={() => updateSettings('fontSize', Math.min(settings.fontSize + 2, 28))}
        >
          <FiPlus size={20} />
          <span className="text-xs mt-1">字体</span>
        </button>
        
        <button
          className="p-3 rounded-full hover:bg-gray-200 dark:hover:bg-gray-700 flex flex-col items-center"
          onClick={toggleTheme}
        >
          {settings.theme === 'light' ? <FiSun size={20} /> : settings.theme === 'dark' ? <FiMoon size={20} /> : <FiSun size={20} />}
          <span className="text-xs mt-1">主题</span>
        </button>
        
        <button
          className="p-3 rounded-full hover:bg-gray-200 dark:hover:bg-gray-700 flex flex-col items-center"
          onClick={() => setShowSettings(!showSettings)}
        >
          <FiSettings size={20} />
          <span className="text-xs mt-1">设置</span>
        </button>
      </div>
      
      {/* 阅读设置面板 */}
      {showSettings && (
        <div className={`${theme.sidebarBg} p-4 shadow-md absolute right-0 z-20 w-full sm:w-72 max-h-[90vh] overflow-y-auto transition-all`}>
          <div className="flex justify-between items-center mb-4">
            <h3 className="font-semibold">阅读设置</h3>
            <button 
              className="p-2 rounded-full hover:bg-gray-200 dark:hover:bg-gray-700"
              onClick={() => setShowSettings(false)}
            >
              <FiX size={20} />
            </button>
          </div>
          
          {/* 离线模式设置 */}
          <div className="mb-4 border-b pb-3">
            <div className="flex justify-between items-center mb-2">
              <label className="text-sm">离线模式</label>
              <button
                className={`px-2 py-1 rounded text-white ${permanentOfflineMode ? 'bg-yellow-500' : 'bg-green-500'}`}
                onClick={toggleOfflineMode}
              >
                {permanentOfflineMode ? '已开启' : '已关闭'}
              </button>
            </div>
            <p className="text-xs text-gray-500">
              {permanentOfflineMode ? 
                '永久离线模式：仅使用已缓存内容，节省流量' : 
                '自动模式：有网络时在线，断网时离线'}
            </p>
          </div>
          
          {/* 编码设置 */}
          <div className="mb-4">
            <label className="block text-sm font-medium mb-1">文本编码</label>
            <select 
              className={`w-full p-2 rounded ${theme.selectBg}`}
              value={settings.encoding}
              onChange={e => updateSettings('encoding', e.target.value)}
            >
              <option value="auto">自动检测</option>
              <option value="utf-8">UTF-8</option>
              <option value="gbk">GBK</option>
            </select>
          </div>
          
          {/* 章节长度设置 */}
          <div className="mb-4">
            <label className="block text-sm font-medium mb-1">
              章节最大长度 ({settings.maxChapterChars} 字符)
            </label>
            <div className="flex items-center">
              <span className="text-xs mr-2">5k</span>
              <input 
                type="range" 
                min="5000" 
                max="50000" 
                step="1000" 
                value={settings.maxChapterChars || 10000}
                onChange={e => updateSettings('maxChapterChars', parseInt(e.target.value))}
                className="flex-1"
              />
              <span className="text-xs ml-2">50k</span>
            </div>
            <p className="text-xs text-gray-500 mt-1">
              调整后需要重新加载内容生效。较小的值对大章节进行更细致的分段。
            </p>
            <button
              className={`mt-2 w-full py-1 px-2 rounded text-sm ${theme.buttonBg} hover:opacity-90`}
              onClick={() => {
                if (content && novel) {
                  // 保存当前阅读位置
                  const currentPosition = contentRef.current ? contentRef.current.scrollTop : 0;
                  // 重新处理内容
                  setLoading(true);
                  // 模拟获取进度，使用当前章节和位置
                  const progress = currentChapter ? {
                    chapterId: currentChapter.id,
                    position: currentPosition
                  } : null;
                  
                  // 延迟一点执行，让UI有时间更新
                  setTimeout(() => {
                    processContent(content, novel, progress).catch(err => {
                      console.error('重新处理内容失败:', err);
                      setError('重新处理内容失败: ' + err.message);
                      setLoading(false);
                    });
                  }, 100);
                } else {
                  showNotification('没有可重新加载的内容', 'warning');
                }
              }}
            >
              重新加载内容以应用设置
            </button>
          </div>
          
          {/* 主题设置 */}
          <div className="mb-4">
            <div className="flex justify-between items-center mb-2">
              <label className="text-sm">主题</label>
              <button
                className={`p-2 rounded-full ${theme.buttonHover}`}
                onClick={toggleTheme}
              >
                {settings.theme === 'light' ? '浅色' : settings.theme === 'dark' ? '深色' : '复古'}
              </button>
            </div>
          </div>
          
          {/* 字体大小设置 - 新增 */}
          <div className="mb-4 border-b pb-3">
            <div className="flex justify-between items-center mb-2">
              <label className="text-sm">字体大小</label>
              <div className="flex items-center">
                <button
                  className={`px-2 py-1 rounded-l ${theme.buttonHover}`}
                  onClick={() => {
                    const newSize = Math.max(14, settings.fontSize - 2);
                    updateSettings('fontSize', newSize);
                  }}
                >
                  -
                </button>
                <span className="px-2">{settings.fontSize}px</span>
                <button
                  className={`px-2 py-1 rounded-r ${theme.buttonHover}`}
                  onClick={() => {
                    const newSize = Math.min(28, settings.fontSize + 2);
                    updateSettings('fontSize', newSize);
                  }}
                >
                  +
                </button>
              </div>
            </div>
          </div>
        </div>
      )}
      
      {/* 显示通知 */}
      {notification && (
        <SimpleNotification 
          message={notification.message}
          type={notification.type}
          onClose={closeNotification}
        />
      )}
    </div>
  );
}

export default Reader;